﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using MarqueeMoment.Entities;
using NLog;
using System.IO;

namespace MarqueeMoment.Forms
{
    public partial class frmArchive : Form
    {
        public static bool formClose = true;
        private static Logger logger = LogManager.GetCurrentClassLogger();

        #region Constructor
        public frmArchive()
        {
            logger.Info("On frmArchive()");
            InitializeComponent();
            InitializeValues();
        }
        #endregion Constructor

        #region BackgroundWorker
        private void bgWorker_DoWork_RefreshList(object sender, DoWorkEventArgs e)
        {
            logger.Info("On bgWorker_DoWork_RefreshList(object sender, DoWorkEventArgs e)");
            DataTable dtGTArchive = ArchiveEntity.SelectAllArchiveWithImage();
            e.Result = dtGTArchive;

        }
        private void bgWorker_Completed_RefreshList(object sender, RunWorkerCompletedEventArgs e)
        {
            logger.Info("On bgWorker_Completed_RefreshList(object sender, RunWorkerCompletedEventArgs e)");
            DataTable dtGTArchive = e.Result as DataTable;
            if (dtGTArchive != null)
                dgGTArchive.DataSource = dtGTArchive;

            bgWorker.DoWork -= bgWorker_DoWork_RefreshList;
            bgWorker.RunWorkerCompleted -= bgWorker_Completed_RefreshList;
        }

        private void bgWorker_DoWork_ViewUnschedule(object sender, DoWorkEventArgs e)
        {
            logger.Info("On bgWorker_DoWork_ViewUnschedule(object sender, DoWorkEventArgs e)");
            DateTime startDate, endDate;
            startDate = monthCalendarArchive.SelectionStart;
            endDate = monthCalendarArchive.SelectionEnd;
            
            logger.Info("startDate without ticks: " + startDate.Date.ToString());
            logger.Info("endDate without ticks: " + endDate.Date.ToString());

            startDate = startDate.Date.AddTicks(dtStartTime.Value.TimeOfDay.Ticks);
            endDate = endDate.Date.AddTicks(dtEndTime.Value.TimeOfDay.Ticks);

            logger.Info("startDate with ticks: " + startDate.Date.ToString());
            logger.Info("endDate with ticks: " + endDate.Date.ToString());
            
            DataSet dsGTArchive = ArchiveEntity.SelectAllArchiveWithImageByFilter(startDate, endDate);
            e.Result = dsGTArchive;

        }
        private void bgWorker_Completed_ViewUnschedule(object sender, RunWorkerCompletedEventArgs e)
        {
            logger.Info("On bgWorker_Completed_ViewUnschedule(object sender, RunWorkerCompletedEventArgs e)");
            DataSet dsGTArchive = e.Result as DataSet;
            if (dsGTArchive != null)
                RefreshGTList(dsGTArchive);

            bgWorker.DoWork -= bgWorker_DoWork_ViewUnschedule;
            bgWorker.RunWorkerCompleted -= bgWorker_Completed_ViewUnschedule;
        }

        #endregion BackgroundWorker

        #region Grid Archive

        /// <summary>
        /// To get ordinal
        /// </summary>
        /// <param name="number">integer number, whose ordinal required</param>
        /// <returns> number with ordinal</returns>
        public static string GetOrdinal(int number)
        {
            logger.Info("On GetOrdinal(int number), number:" + number.ToString());
            string result = string.Empty;
            if (number == 11 || number == 12 || number == 13)
                return result + "th";
            switch (number % 10)
            {
                case 1: result += "st"; break;
                case 2: result += "nd"; break;
                case 3: result += "rd"; break;
                default: result += "th"; break;
            }
            logger.Info("On GetOrdinal(int number),result:" + result);
            return result;
        }

        /// <summary>
        /// Reschedule the selection 
        /// </summary>
        /// <param name="archiveId">Selected Archive ID</param>
        private void ScheduleGT(Int32 archiveId)
        {
            logger.Info("On ScheduleGT(Int32 archiveId) with archiveId:" + archiveId.ToString());
            try
            {
                ArchiveEntity archive = new ArchiveEntity();
                archive.ArchiveId = archiveId;

                archive = ArchiveEntity.Select(archive.ArchiveId);
                if (archive != null)
                {
                    ImageEntity imageValue = ImageEntity.Select(archive.ImageId);
                    if (imageValue != null)
                    {
                        if (!Directory.Exists(Common.composedPhotoDirPath))
                            Directory.CreateDirectory(Common.composedPhotoDirPath);

                        //Increment ImageIndex
                        Common.imageIndex++;
                        FileStream FS1 = new FileStream(MarqueeMoment.Entities.Common.composedPhotoPath(), FileMode.Create);
                        byte[] blob = imageValue.ImageData;
                        FS1.Write(blob, 0, blob.Length);
                        FS1.Close();
                        FS1 = null;

                        this.Visible = false;
                        frmScheduleScreen obSchedule = new frmScheduleScreen(archive);
                        obSchedule.ShowDialog();
                        this.Close();
                    }
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error on Reshudling image, see log file for more details");
            }

        }


        public void buttonScheduleClick(object sender, EventArgs e, Int32 archiveId)
        {
            logger.Info("On buttonScheduleClick(object sender, EventArgs e, Int32 archiveId) with archiveId:" + archiveId.ToString());
            ScheduleGT(archiveId);
        }

        /// <summary>
        /// It is used for refiling grid with Archived record. 
        /// </summary>
        /// 
        private void RefreshGTList(DataSet dsSchedule)
        {
            logger.Info("On RefreshGTList(DataSet dsSchedule)");
            DataTable dtGTSchedule = null;
            if (dsSchedule == null)
            {
                DataSet dataset = ArchiveEntity.SelectAllArchiveWithImages();
                if (dataset != null && dataset.Tables.Count > 0)
                {
                    for (int count = 0; count < pnlList.Controls.Count; count++)
                    {
                        ScheduleControl listUserControl = pnlList.Controls[count] as ScheduleControl;
                        if (listUserControl != null)
                            if (listUserControl.picBox.Image != null)
                                listUserControl.picBox.Image.Dispose();

                    }
                    dtGTSchedule = dataset.Tables[0];
                }
            }
            else
                dtGTSchedule = dsSchedule.Tables[0];

            ScheduleControl userControl;
            Int32 yPOS = 20;
            pnlList.Controls.Clear();

            for (int count = 0; count < dtGTSchedule.Rows.Count; count++)
            {
                Int32 archiveId = Int32.Parse(dtGTSchedule.Rows[count]["ArchiveId"].ToString());
                userControl = new ScheduleControl(archiveId, true);

                DateTime dtScheduletime = (DateTime)dtGTSchedule.Rows[count]["ArchiveTime"];

                userControl.lblTime.Text = dtScheduletime.ToLongTimeString();
                userControl.lblArchiveTime.Visible = true;

                userControl.lblArchiveTime.Text = dtScheduletime.ToString("ddd, MMM dd");
                userControl.lblArchiveTime.Text += GetOrdinal(dtScheduletime.Day);
                userControl.btnReschedule.Visible = true;
                userControl.btnReschedule.Image = global::MarqueeMoment.Properties.Resources.schedule_bttn;

                if (dtGTSchedule.Rows.Count > 3)
                    userControl.Width = pnlList.Width - 22;
                else
                    userControl.Width = pnlList.Width - 2;

                if (userControl.picBox.Image != null)
                    userControl.picBox.Image.Dispose();

                byte[] blob = (byte[])dtGTSchedule.Rows[count]["ImageData"];
                MemoryStream ms = new MemoryStream(blob);
                Image returnImage = Image.FromStream(ms);

                userControl.picBox.Image = returnImage;
                userControl.picBox.SizeMode = PictureBoxSizeMode.StretchImage;
                userControl.picBox.Refresh();

                userControl.Location = new System.Drawing.Point(2, yPOS);
                pnlList.Controls.Add(userControl);

                yPOS = yPOS + userControl.Height + 10;
            }
        }


        private void refreshList()
        {
            logger.Info("On refreshList()");
            try
            {
                dgGTArchive.DataSource = null;
                dgGTArchive.Columns.Clear();

                DataGridViewTextBoxColumn ArchiveId = new DataGridViewTextBoxColumn();
                ArchiveId.DataPropertyName = "ArchiveId";
                ArchiveId.Name = "ArchiveId";
                ArchiveId.HeaderText = "ArchiveId";
                ArchiveId.Width = 10;
                ArchiveId.Visible = false;

                DataGridViewImageColumn ImageData = new DataGridViewImageColumn();
                ImageData.DataPropertyName = "ImageData";
                ImageData.Name = "ImageData";
                ImageData.HeaderText = "Archived Composition";
                ImageData.Width = 280;
                ImageData.ImageLayout = DataGridViewImageCellLayout.Stretch;

                DataGridViewTextBoxColumn ArchiveTime = new DataGridViewTextBoxColumn();
                ArchiveTime.DataPropertyName = "ArchiveTime";
                ArchiveTime.Name = "ArchiveTime";
                ArchiveTime.HeaderText = "Archive Time";
                ArchiveTime.Width = 195;
                ArchiveTime.DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomLeft;



                dgGTArchive.Columns.Add(ArchiveId);
                dgGTArchive.Columns.Add(ImageData);
                dgGTArchive.Columns.Add(ArchiveTime);


                if (bgWorker.IsBusy != true)
                {
                    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_RefreshList);
                    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_RefreshList);
                    bgWorker.RunWorkerAsync();
                }
            }
            catch (Exception exc)
            {
                logger.Error(exc.StackTrace);
                Dialogs.Error("Error on showing archive list");

            }
        }

        /// <summary>
        /// To Show Time on Time Box
        /// </summary>
        private void ShowTime()
        {
            String currentTime = String.Empty;
            var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            currentTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZone).ToLongTimeString();
            lblPM.Text = currentTime.Substring(currentTime.Length - 2);
            currentTime = currentTime.Substring(0, currentTime.Length - 3);

            lblT8.Text = currentTime.Substring(currentTime.Length - 1);
            lblT7.Text = currentTime.Substring(currentTime.Length - 2, 1);
            lblT6.Text = currentTime.Substring(currentTime.Length - 3, 1);
            lblT5.Text = currentTime.Substring(currentTime.Length - 4, 1);
            lblT4.Text = currentTime.Substring(currentTime.Length - 5, 1);
            lblT3.Text = currentTime.Substring(currentTime.Length - 6, 1);
            lblT2.Text = currentTime.Substring(currentTime.Length - 7, 1);

            if (currentTime.Length == 7)
                lblT1.Text = String.Empty;
            else
                lblT1.Text = currentTime.Substring(currentTime.Length - 8, 1);
        }

        /// <summary>
        /// To Initialize Values
        /// </summary>
        private void InitializeValues()
        {
            logger.Info("On InitializeValues()");
            ShowTime();

            //Delete old archive records from db
            var timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
            DateTime currentDate = TimeZoneInfo.ConvertTime(DateTime.Now, timeZone);
       //     ArchiveEntity.DeleteOldArchive(currentDate.AddDays(-7));
            RefreshGTList(null);
            dtStartTime.Text = "12:00:00 AM";
            dtEndTime.Text = "11:59:00 PM";
        }

        #endregion Grid Archive

        #region System Events

        private void btnMenu_Click(object sender, EventArgs e)
        {
            logger.Info("On btnMenu_Click(object sender, EventArgs e)");
            this.Close();
        }

        private void btnViewUnschedule_Click(object sender, EventArgs e)
        {
            logger.Info("On btnViewUnschedule_Click(object sender, EventArgs e) with bgWorker.IsBusy:" + bgWorker.IsBusy.ToString());
            if (bgWorker.IsBusy != true)
            {
                bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_ViewUnschedule);
                bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_ViewUnschedule);
                bgWorker.RunWorkerAsync();
            }
        }

        private void btnClearFilter_Click(object sender, EventArgs e)
        {
            logger.Info("On btnClearFilter_Click(object sender, EventArgs e)");
            RefreshGTList(null);
            //if (bgWorker.IsBusy != true)
            //{
            //    bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork_RefreshList);
            //    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Completed_RefreshList);
            //    bgWorker.RunWorkerAsync();
            //}
        }

        private void frmArchive_FormClosing(object sender, FormClosingEventArgs e)
        {
            logger.Info("On frmArchive_FormClosing(object sender, FormClosingEventArgs e), with formClose:" + formClose.ToString());
            if (!formClose)
            {
                this.Visible = true;
                e.Cancel = true;
                formClose = true;
                return;
            }
        }

        private void timerArchive_Tick(object sender, EventArgs e)
        {
           ShowTime();
        }


        #endregion System Events

        private void dtEndTime_ValueChanged(object sender, EventArgs e)
        {

        }

    }
}
